package com.atguigu.gateway.filter;


import org.springframework.cloud.gateway.filter.GatewayFilter;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.factory.AbstractNameValueGatewayFilterFactory;
import org.springframework.http.HttpHeaders;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;

import java.util.UUID;

//定义一个名为OnceTokenGatewayFilterFactory的组件类，用于生成一次性令牌的网关过滤器
@Component
public class OnceTokenGatewayFilterFactory extends AbstractNameValueGatewayFilterFactory {
    /**
     * 重写apply方法，创建并返回一个自定义的GatewayFilter实例
     * 该过滤器用于在响应中添加一次性令牌，如uuid、jwt等
     *
     * @param config 包含名称和值的配置对象，用于指定令牌类型和名称
     * @return 返回一个自定义的GatewayFilter实例
     */
    @Override
    public GatewayFilter apply(NameValueConfig config) {
        return new GatewayFilter() {
            /**
             * 实现filter方法，为每个请求添加一次性令牌
             * 该方法在请求处理链中执行，并在响应前添加令牌
             *
             * @param exchange 服务器与客户端之间的交换对象，包含请求和响应
             * @param chain 过滤器链，用于将控制权传递给下一个过滤器
             * @return 返回一个Mono<Void>，表示异步操作的完成
             */
            @Override
            public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
               //每次响应之前，添加一个一次性令牌，支持uuid,jwt等各种格式
                return chain.filter(exchange).then(Mono.fromRunnable(()->{
                    ServerHttpResponse response=exchange.getResponse();
                    HttpHeaders headers=response.getHeaders();
                    String value=config.getValue();
                    //根据配置生成对应类型的令牌值
                    if("uuid".equalsIgnoreCase(value)){
                        value= UUID.randomUUID().toString();
                    }
                    if("jwt".equalsIgnoreCase(value)){
                        value="eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM4NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9.TJVA95OrM7E2cBab30RMHrHDcEfxjoYZgeFONFh7HgQ";
                    }
                    //将生成的令牌添加到响应头中
                    headers.add(config.getName(),value);
                }));
            }
        };
    }
}
